/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2015年7月6日
 * V4.0
 */
package com.jphenix.driver.ftp;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.jphenix.kernel.baseobject.instanceb.ABase;
import com.jphenix.sdk.ftp.FtpDirEntry;
import com.jphenix.sdk.ftp.FtpDirParser;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.share.util.SFilesUtil;
import com.jphenix.standard.docs.ClassInfo;


/**
 * 
 * JDK1.6跟JDK1.7中都有FtpClient类，但是方法却不一样，次奥啊
 * 为了兼顾JDK1.6，于是乎将JDK1.7中的ftp源码囊括进来了
 * 该类中调用的都是移植JDK1.7中的FTP模块
 * 
 * 
 * FTP客户端类
 * 注意：不要直接调用，通过FTP管理类获取指定连接源的类实例
 * @author 马宝刚
 * 2015年7月6日
 */
@ClassInfo({"2015-07-06 17:20","FTP客户端类"})
public class FtpClient extends ABase {

    protected com.jphenix.sdk.ftp.FtpClient fc = null; //ftp客户端核心类实例
    protected String ip = null; //连接地址
    protected int port = 21; //连接端口
    protected boolean pasv = true; //是否采用被动传输模式
    protected String user = null; //登录用户名
    protected String pwd = null; //登录密码
    protected String path = null; //目标根路径
    protected long lastTime = 0; //上次执行时间
    protected FtpDirParser dirParser = null; //目录信息解析类
    
    
    
    /**
     * 构造函数
     * @author 马宝刚
     */
    public FtpClient() {
        super();
    }
    
    /**
     * 获取文件列表
     * @param filePath 文件路径
     * @return  文件列表
     * @throws Exception 异常
     * 2015年7月6日
     * @author 马宝刚
     */
    public List<String> listFiles(String filePath) throws Exception {
        lastTime = System.currentTimeMillis();
        log("Begin ListFiles:["+filePath+"]");
        //文件迭代
        Iterator<FtpDirEntry> iter = fc.listFiles(filePath);
        //构建返回值
        List<String> reList = new ArrayList<String>();
        FtpDirEntry fde = null;
        while(iter.hasNext()) {
            fde = iter.next();
            reList.add(fde.getName());
        }
        log("ListFiles Over:["+filePath+"]");
        return reList;
    }
    
    /**
     * 获取当前文件夹路径
     * @return 当前文件夹路径
     * @throws Exception 异常
     * 2015年7月8日
     * @author 马宝刚
     */
    public String pwd() throws Exception {
        log("Begin PWD");
        lastTime = System.currentTimeMillis();
        return fc.getWorkingDirectory();
    }
    
    /**
     * 进入子文件夹
     * @param path 子文件夹
     * @param needCreate 如果文件夹不存在，是否需要建立
     * @throws Exception 异常
     * 2015年7月8日
     * @author 马宝刚
     */
    public void changeDirectory(String path,boolean needCreate) throws Exception {
        log("Begin ChangeDirectory ["+path+"] needCreate:["+needCreate+"]");
        //整理路径分隔符
        path = BaseUtil.swapString(path,"\\","/");
        if(needCreate) {
            //路径数组
            String[] pathArr = BaseUtil.split(path,"/");
            for(String pathEle:pathArr) {
                if(pathEle.length()<1) {
                    continue;
                }
                try {
                    log("Begin into Path:["+pathEle+"]");
                    //尝试进入子文件夹
                    fc.changeDirectory(pathEle);
                    log("Into Path:["+pathEle+"] Over");
                }catch(Exception e) {
                    //进入失败时，认定为文件夹不存在
                    log("Into Exception:["+e+"] Begin Create:["+pathEle+"]");
                    //建立子文件夹
                    fc.makeDirectory(pathEle);
                    log("Begin into Path2:["+pathEle+"]");
                    //再重新进入
                    fc.changeDirectory(pathEle);
                    log("Into Path2:["+pathEle+"] Over");
                }
            }
        }else {
            fc.changeDirectory(path);
        }
        log("Change Path:["+path+"] Over");
    }
    
    
    /**
     * 下载文件
     * @param filePath 文件路径
     * 2015年7月6日
     * @author 马宝刚
     * @return 文件输出流
     */
    public OutputStream getFile(String filePath) throws Exception {
        lastTime = System.currentTimeMillis();
        log("Begin getFile:["+filePath+"]");
        return fc.putFileStream(filePath);
    }
    
    /**
     * 删除文件夹
     * @param path 文件夹路径
     * @throws Exception 异常
     * 2015年7月6日
     * @author 马宝刚
     */
    public void removeDirectory(String path) throws Exception {
        lastTime = System.currentTimeMillis();
        log("Begin RemoveDirectory:["+path+"]");
        fc.removeDirectory(path);
    }
    
    /**
     * 删除指定文件
     * @param filePath 文件路径
     * @throws Exception 异常
     * 2015年7月6日
     * @author 马宝刚
     */
    public void delete(String filePath) throws Exception {
        lastTime = System.currentTimeMillis();
        log("Begin Delete :["+filePath+"]");
        fc.deleteFile(filePath);
    }
    
    
    /**
     * 传送文件
     * @param filePath 文件路径
     * @throws Exception 异常
     * 2015年7月6日
     * @author 马宝刚
     */
    public void upload(String filePath) throws Exception {
        lastTime = System.currentTimeMillis();
        log("Begin Upload:["+filePath+"]");
        InputStream is = null;
        try {
            is = SFilesUtil.getFileInputStreamByUrl(filePath,null);
            fc.putFile(SFilesUtil.getFileName(filePath),is);
        }catch(Exception e) {
            e.printStackTrace();
            throw e;
        }finally {
            try {
                is.close();
            }catch(Exception e2) {}
        }
    }
    
    
    /**
     * 建立自路径
     * @param path 路径
     * @throws Exception 异常
     * 2015年7月6日
     * @author 马宝刚
     */
    public void makeDirectory(String path) throws Exception {
        lastTime = System.currentTimeMillis();
        log("Begin MakeDirectory :["+path+"]");
        fc.makeDirectory(path);
    }

    /**
     * 建立连接
     * 2015年7月6日
     * @param reConnect 是否重新连接（强制重新连接）
     * @author 马宝刚
     * @throws Exception 异常
     */
    public void connect(boolean reConnect) throws Exception {
        lastTime = System.currentTimeMillis();
        if(fc==null || !fc.isConnected() || reConnect) {
            fc = com.jphenix.sdk.ftp.FtpClient.create();
            log("Begin Link Ftp IP:["+ip+"] port:["+port+"] pasv:["
                    +pasv+"] uName:["+user+"] pwd:["+pwd+"] basePath:["+path+"]");
            if(dirParser!=null) {
            	fc.setDirParser(dirParser);
            }
            //建立连接
            fc.connect(new InetSocketAddress(ip,port));
            //执行登录
            fc.login(user,pwd.toCharArray());
            
            fc.setBinaryType();
            fc.enablePassiveMode(pasv);
            
            if(path!=null && path.length()>0) {
                fc.changeDirectory(path);
            }
        }
    }
    
    /**
     * 关闭连接
     * 2015年7月6日
     * @author 马宝刚
     */
    public void close() {
        log("Begin Close FTP");
        try {
            fc.close();
        }catch(Exception e) {}
    }
}
